package com.octopussy.g3dview {
import away3d.cameras.HoverCamera3D;
import away3d.containers.ObjectContainer3D;
import away3d.containers.View3D;
import away3d.core.base.Mesh;
import away3d.core.base.Object3D;
import away3d.core.render.Renderer;
import away3d.lights.DirectionalLight3D;
import away3d.lights.PointLight3D;
import away3d.loaders.Obj;

import flash.display.Sprite;
import flash.events.Event;
import flash.geom.Vector3D;

public class G3DScene extends Sprite {

    private var _camera:HoverCamera3D;
    private var _view:View3D;
    private var _objData:*;

    private var _objectManager:ObjectManager;
    private const MIN_DISTANCE:Number = 150;
    private var _light:PointLight3D;

    public function G3DScene( objectManager:ObjectManager, width:int, height:int, objData:* ) {
        super();

        _objectManager = objectManager;

        _objData = objData;

        _camera = new HoverCamera3D( { yfactor:1.1, distance:1000, steps:1, zoom:50} );
        _camera.panAngle = 155;
        _camera.tiltAngle = 25;
        _camera.hover( true );
        _view = new View3D( {x:width / 2, y:height / 2, camera: _camera } );

        _view.renderer = Renderer.BASIC;
        addChild( _view );

        /*   _light = new DirectionalLight3D();
         _light.direction = new Vector3D( 500, -200, 500 );*/
        _light = new PointLight3D( {x: 500, y: 100, z:  500, diffuse: 3, ambient: 1, specular:0 } );
        _light.color = 0xa0a0a0;
        updateLight();
        _view.scene.addLight( _light );

        addEventListener( Event.ENTER_FRAME, onEnterFrame );

        const obj:Object3D = Obj.parse( _objData, {useGroups: true} );
        _view.scene.addChild( obj );

        if ( obj is ObjectContainer3D ) {
            for each( var child:Object3D in (obj as ObjectContainer3D).children )
                addObject( child );
        }
    }

    public function setSize( w:int, h:int ):void {
        _view.x = w / 2;
        _view.y = h / 2;
    }

    public function tilt( value:Number ):void {
        _camera.tiltAngle += value;
    }

    public function pan( value:Number ):void {
        _camera.panAngle += value;
    }

    private function updateLight():void {
        const v:Vector3D = _camera.position;
        v.normalize();
        v.scaleBy( 800 );
        _light.position = v;
        // _light.position.scaleBy( 1000 );
    }

    public function zoom( value:Number ):void {
        _camera.distance = Math.max( _camera.distance - value * 10, MIN_DISTANCE );
    }

    private function onEnterFrame( event:Event ):void {
        _camera.hover();
        updateLight();
        _view.render();
    }

    private function addObject( obj:Object3D ):void {
        if ( obj is Mesh )
            _objectManager.registerObject( obj as Mesh );
    }
}
}
